//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Scene2D/Types/Types.h"
#include "Scene2D/Render/RenderQueue.h"
#include "Scene2D/Types/SceneObjMsg.h"
#include "Scene2D/Sound/SoundManager.h"

namespace Engine
{
namespace Scene2D
{

	//
	// Scene Manager 2D
	//

	class SceneManager : public BaseObject
	{
	// types
	private:
		typedef array< Ptr< SceneObject > >		scene_objects_t;


	// variables
	private:
		Physics2D::PhysicsWorld		_physWorld;
		SoundManager				_soundMngr;
		RenderQueue					_renderQueue;
		scene_objects_t				_objects;
		Ptr< SceneCamera >			_activeCamera;


	// methods
	public:
		SceneManager (const EngineSubSystemsRef ess);
		~SceneManager ();


		void Update (float timeDelta);
		void Draw ();

		void Attach (SceneObject *obj);
		void Detach (SceneObject *obj);
		void DetachAll ();

		bool Load (uni_c_string filename);
		bool Create ();
		void Destroy ();

		Physics2D::PhysicsWorld *	GetPhysicsWorld ()		{ return &_physWorld; }
		RenderQueue *				GetRenderQueue ()		{ return &_renderQueue; }
		SoundManager *				GetSoundManager ()		{ return &_soundMngr; }

		Ptr< SceneCamera >			GetActiveCamera ()		{ return _activeCamera; }

		void SetCamera (SceneCamera *cam)					{ _activeCamera = cam; }


	private:
		void _SendMessageToAll (const SceneObjMsg &msg);
	};


	
/*
=================================================
	constructor
=================================================
*/
	inline SceneManager::SceneManager (const EngineSubSystemsRef ess) :
		BaseObject(ess), _soundMngr(ess)
	{
	}
	
/*
=================================================
	destructor
=================================================
*/
	inline SceneManager::~SceneManager ()
	{
	}
	
/*
=================================================
	Update
----
	TODO: support running in parallel thread
=================================================
*/
	inline void SceneManager::Update (float timeDelta)
	{
		typedef SceneObjMsg		SO;

		_renderQueue.Clear();

		_physWorld.Update( timeDelta, 6, 2 );

		_SendMessageToAll( SO( SO::UPDATE, SO::Update( timeDelta ) ) );
	}
	
/*
=================================================
	Create
=================================================
*/
	inline bool SceneManager::Create ()
	{
		_physWorld.Create();
		_soundMngr.Create();
		return true;
	}

/*
=================================================
	Destroy
=================================================
*/
	inline void SceneManager::Destroy ()
	{
		DetachAll();
		_renderQueue.Clear();
		_physWorld.Destroy();
		_soundMngr.Destroy();
	}


}	// Scene2D
}	// Engine